﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.Web.Mvc;
using System.Reflection;
using Direct.Bootstrap;
using System.IO;
using Direct;

namespace Direct.Server.Application
{
    public class DirectServerApplication : System.Web.HttpApplication, IBootLogger, IPathMapper
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",
                "{controller}/{action}",
                new { controller = "R", action = "Index" });
        }

        private string _bootLogFilePath;
        private Object __logLockObject = new Object();
        public void Log(String message, Exception ex = null)
        {
            try
            {
                lock (__logLockObject)
                {
                    File.AppendAllText(_bootLogFilePath, String.Format("{0}{1}: {2}", Environment.NewLine, DateTime.Now.ToString(), message)
                        + (ex == null ? "" : String.Format("{0}     Exception: {1}", Environment.NewLine, ex.ToString())));
                }
            }
            catch { }
        }

        private bool SafeExec(String message, Action action)
        {
            var result = true;
            Log(message);
            try
            {
                action();
            }
            catch (Exception ex)
            {
                result = false;
                Log("ERROR: ", ex);
            }
            return result;
        }

#if DEBUG
        Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            this.Log("Resolving assembly " + args.Name);
            return null;
        }
#endif

        protected void Application_Start()
        {
#if DEBUG
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
#endif

            _bootLogFilePath = Server.MapPath("~/App_Data/Server/boot.txt");
            Directory.CreateDirectory(Path.GetDirectoryName(_bootLogFilePath));
            if (!File.Exists(_bootLogFilePath))
                File.WriteAllText(_bootLogFilePath, String.Format("File Created: {0} \n Path: {1}", DateTime.Now.ToString(), _bootLogFilePath));
            File.AppendAllText(_bootLogFilePath, "\r\n\r\n\r\n");
            Log("Server starting");
            File.AppendAllText(_bootLogFilePath, Environment.NewLine + Environment.NewLine + "-------------------------------------------------------------------------------------");

            var bootstrapper = new Bootstrapper();
            bootstrapper.Run(this, this);

            RegisterRoutes(RouteTable.Routes);

            //model binders
            ModelBinders.Binders[typeof(Decimal)]
                = ModelBinders.Binders[typeof(Decimal?)]
                = ModelBinders.Binders[typeof(float)]
                = ModelBinders.Binders[typeof(Double)]
                = ModelBinders.Binders[typeof(Double?)]
                = ModelBinders.Binders[typeof(int)]
                = ModelBinders.Binders[typeof(int?)]
                = ModelBinders.Binders[typeof(Boolean)]
                = ModelBinders.Binders[typeof(Boolean?)]
                = new Direct.Server.Mvc.PrimitiveValueBinder();

            PostInit();
        }

        public string MapPath(string relativePath)
        {
            return Server.MapPath(relativePath);
        }

        protected virtual void PostInit() { }

    }
}
